package bb

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Point
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.ImageButton
import android.widget.SeekBar
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProviders
import com.blankj.utilcode.util.PathUtils
import com.blankj.utilcode.util.ToastUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import oa.lla.cca.R
import com.clean.scanlibrary.bean.CurrencyInfoBean
import com.clean.scanlibrary.bean.DiscernInfoBean
import com.clean.scanlibrary.bean.DiscernTokenBean
import com.clean.scanlibrary.bean.WordInfoBean
import com.clean.scanlibrary.camera.utils.FileUtil
import bc.EZ
import bc.CF
import com.clean.scanlibrary.dialog.BlackAndWhiteDialog
import com.clean.scanlibrary.dialog.DiscernTipsDialog
import com.clean.scanlibrary.dialog.LoadingDialog
import com.clean.scanlibrary.http.DiscernViewMode
import com.clean.scanlibrary.utils.SPreference
import com.google.common.util.concurrent.ListenableFuture
import com.clean.scanlibrary.camera.utils.Utils
import com.clean.scanlibrary.camera.utils.YuvToRgbConverter
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

class CP: AppCompatActivity() {

    private var imageCapture: ImageCapture? = null
    private var mCameraControl: CameraControl? = null
    private var mCameraInfo: CameraInfo? = null
    private var focusView: CF? = null
    private var isInfer = false
    private var imageRotationDegrees: Int = 0
    private var flashMode: Int = ImageCapture.FLASH_MODE_OFF
    private var photoViewButton: ImageButton? = null
    private var linearZoom: SeekBar? = null
    private var lightZoom: SeekBar? = null
    private var viewFinder: PreviewView? = null
    // 使用后摄像头
    private var cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    private var hasGetPermission by SPreference("ISHASCAMERAPERMISS",false)
    private lateinit var cameraExecutor: ExecutorService
    private lateinit var bitmapBuffer: Bitmap
    private lateinit var converter: YuvToRgbConverter
    private var loadingDialog: LoadingDialog? = null
    private var viewMode: DiscernViewMode? = null
    private var discernTokenBean : DiscernTokenBean? = null
    private var viewType:Int = 0
    private var currentPic:String = ""
    companion object {
        const val SEEK_BAR_MAX = 100.0
        const val LIGHT_SEEK_BAR_MAX = 255.0
        const val LIGHT_INIT = 0.5f
        const val LINEAR_ZOOM_MAX = 1.0
        const val REQUEST_CODE_PERMISSIONS = 10
        val REQUIRED_PERMISSIONS =
            arrayOf(Manifest.permission.CAMERA, Manifest.permission.MANAGE_EXTERNAL_STORAGE)
        private const val TAG = "CP"

        const val VIEW_FROM_MT_LAND = 1 //风景去噪
        const val VIEW_FROM_MT_ANIME_AVATAR = 2 //动漫化身
        const val VIEW_FROM_MT_BEAUTY_TECHNOLOGY= 3//美颜技术
        const val VIEW_FROM_MT_PIXEL_STYLE = 4 //像素风          无权限 GATEWAY_AUTHORIZED_NOT_MATCH
        const val VIEW_FROM_MT_VERSATILE_FILTER = 5//百变滤镜   无权限 GATEWAY_AUTHORIZED_NOT_MATCH
        const val VIEW_FROM_MT_FACE_CHANGE = 6//神奇变脸   不好用 经常识别不出人脸
        const val VIEW_FROM_MT_FOOD_SEPARATION = 7//食物分割
        const val VIEW_FROM_MT_IMAGE_QUALITY_RESTORA=8//图像画质修复
        const val VIEW_FROM_MT_PHOTO_MAKE=9//证件照生成 无权限 GATEWAY_AUTHORIZED_NOT_MATCH
        const val VIEW_FROM_MT_IMAGE_STYLE=10//图像风格化
        const val VIEW_FROM_MT_XIAN_GAO = 11//线稿

        const val VIEWFROMTYPE = "viewFromType"

        fun startNewMtCameraMaginActivity(context: Context, viewFromType:Int){
            val intent: Intent = Intent(context,CP::class.java)
            intent.putExtra(VIEWFROMTYPE,viewFromType)
            context.startActivity(intent)
        }

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_mt_camera_layout)

        viewType = intent.getIntExtra(VIEWFROMTYPE,0)
        initData()
        immersionStatusBar()
        initListener()
        linearZoom = findViewById(R.id.linear_zoom)
        lightZoom = findViewById(R.id.light_zoom)
        viewFinder = findViewById<PreviewView>(R.id.viewFinder)
        linearZoom?.progress = 0
        val light = LIGHT_INIT
        setWindowBrightness(light)
        lightZoom?.progress = (light * LIGHT_SEEK_BAR_MAX).toInt()
        // 对焦框控件、
        focusView = findViewById(R.id.focus_view)
        // 请求权限
        if (allPermissionsGranted()) {
            startCamera()
        } else {
            if (!hasGetPermission){
                ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
            }else{
                Toast.makeText(this, "没有相机授权与本地存储权限授权，无法使用！", Toast.LENGTH_SHORT).show()
                finish()
            }
        }
        cameraExecutor = Executors.newSingleThreadExecutor()
        // 把图像数据转换为RGB格式图像
        converter = YuvToRgbConverter(this)
        // 打开自定义相册
        photoViewButton = findViewById<ImageButton>(R.id.photo_view_button)

    }

    private fun initListener() {
        findViewById<View>(R.id.back)?.setOnClickListener {
            finish()
        }


        lightZoom?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                val current = (progress / LIGHT_SEEK_BAR_MAX).toFloat()
                setWindowBrightness(current)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
            }

        })


        linearZoom?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            @SuppressLint("LongLogTag")
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                val current = (progress / SEEK_BAR_MAX).toFloat()
                Log.e(
                    TAG,
                    "onProgressChanged: progress:$progress, current:$current, mCameraControl: $mCameraControl"
                )
                mCameraControl?.setLinearZoom(current)
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
            }
        })

        // 点击拍照
        findViewById<ImageButton>(R.id.camera_capture_button).setOnClickListener { takePhoto() }

        // 切换摄像头
        findViewById<ImageButton>(R.id.camera_switch_button).setOnClickListener {
            cameraSelector = if (CameraSelector.DEFAULT_FRONT_CAMERA == cameraSelector) {
                CameraSelector.DEFAULT_BACK_CAMERA
            } else {
                CameraSelector.DEFAULT_FRONT_CAMERA
            }
            // 重启相机
            startCamera()
        }

        photoViewButton?.setOnClickListener {
            val intent = Intent(this, EY::class.java)
            startActivity(intent)
        }



        // 切换闪光灯模式
        findViewById<ImageButton>(R.id.flash_switch_button).setOnClickListener {
            when (flashMode) {
                ImageCapture.FLASH_MODE_OFF -> {
                    flashMode = ImageCapture.FLASH_MODE_ON
                    findViewById<ImageButton>(R.id.flash_switch_button).setImageResource(R.drawable.open_flash)
                }
                ImageCapture.FLASH_MODE_ON -> {
                    flashMode = ImageCapture.FLASH_MODE_AUTO
                    findViewById<ImageButton>(R.id.flash_switch_button).setImageResource(R.drawable.auto_flash)
                }
                ImageCapture.FLASH_MODE_AUTO -> {
                    flashMode = ImageCapture.FLASH_MODE_OFF
                    findViewById<ImageButton>(R.id.flash_switch_button).setImageResource(R.drawable.stop_flash)
                }
            }
            // 重启相机
            startCamera()
        }

    }


    /**
     * 沉浸式状态栏
     */
    private fun immersionStatusBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val window: Window = window
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
            // 沉浸式状态栏
            window.decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            // 状态栏改为透明
            window.statusBarColor = Color.TRANSPARENT
        }
    }


    private fun initData(){
        loadingDialog =
            LoadingDialog(this, R.style.dialog)
        //loadingDialog?.show()

        viewMode = ViewModelProviders.of(this).get(DiscernViewMode::class.java)

        //接口异常提示
        viewMode?.posHttpError?.observe(this
        ) {
            loadingDialog?.dismiss()
            Toast.makeText(this,it, Toast.LENGTH_SHORT).show()}

        //---------------------------------美团----------------------
        //风景去噪，返回的平台带美团AI开放平台 水印
        viewMode?.getMtLandscapeLiveData?.observe(this){
           Log.d("HttpManager","风景去噪》》"+it.toString())
            loadingDialog?.dismiss()

            if(it.media_info_list == null){
                Toast.makeText(this@CP, "获取信息失败", Toast.LENGTH_SHORT).show()
                return@observe
            }

            if (it != null) {
                val picDialo: BlackAndWhiteDialog = BlackAndWhiteDialog(this,R.style.dialog)
                picDialo.showPicView(currentPic,it.media_info_list[0].media_data)
                picDialo.show()
            } else {
                Toast.makeText(this@CP, "获取信息失败", Toast.LENGTH_SHORT).show()
            }
        }
    }



    //本地拍照文件进行Base64编码
    @RequiresApi(Build.VERSION_CODES.O)
    fun getFileContentAsBase64(path: String?): String? {
        val b: ByteArray = Files.readAllBytes(Paths.get(path))
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Base64.getEncoder().encodeToString(b)
        } else {
            ""
        }
    }

    private fun toUploadPrc(path:String){
        currentPic = path
        loadingDialog?.show()
        if(TextUtils.isEmpty(path)){
            ToastUtils.showShort("识别异常，请稍后重试。")
            return
        }

        when(viewType){

            VIEW_FROM_MT_LAND ->{
                viewMode?.toMeiTuanloadLandScape(path)
            }

            VIEW_FROM_MT_ANIME_AVATAR ->{
                viewMode?.toMeiTuanAnimeAvatar(path)
            }

            VIEW_FROM_MT_BEAUTY_TECHNOLOGY ->{
                viewMode?.toMeiTuanBeautyTechnology(path)
            }

            VIEW_FROM_MT_PIXEL_STYLE ->{
                viewMode?.toMeiTuanpPixelStyle(path)
            }

            VIEW_FROM_MT_VERSATILE_FILTER ->{
                viewMode?.toMeiTuanpVersatileFilter(path)
            }

            VIEW_FROM_MT_FACE_CHANGE ->{
                viewMode?.toMeiTuanpFaceChanging(path)
            }

            VIEW_FROM_MT_FOOD_SEPARATION ->{
                viewMode?.toMeiTuanFoodSeparation(path)
            }

            VIEW_FROM_MT_IMAGE_QUALITY_RESTORA ->{
                viewMode?.toMeiTuanImageQualityRestore(path)
            }

            VIEW_FROM_MT_PHOTO_MAKE ->{
                viewMode?.toMeiTuanPhotoMake(path)
            }

            VIEW_FROM_MT_IMAGE_STYLE ->{
                viewMode?.toMeiTuanImageStyle(path)
            }

            VIEW_FROM_MT_XIAN_GAO ->{
                viewMode?.toMeiTuanXianGaoStyle(path)
            }

            else->{
                viewMode?.toUploadPicInfo(discernTokenBean?.access_token!!,path,viewType)
            }
        }
    }


    //调用接口识别之后展示一个提示信息弹唱（暂时定义一个弹窗）
    private fun showTipsDialog(dataList: ArrayList<DiscernInfoBean>){
        val dialog : DiscernTipsDialog = DiscernTipsDialog(this, R.style.dialog)
        dialog.setInfoData(dataList,currentPic)
        dialog.show()
    }


    //调用接口识别之后展示一个提示信息弹唱（暂时定义一个弹窗）
    private fun showWordsDialog(dataBean: WordInfoBean){
        val dialog : DiscernTipsDialog = DiscernTipsDialog(this, R.style.dialog)
        dialog.setWordsInfoData(dataBean,currentPic)
        dialog.show()
    }


    private fun showCurrencyDialog(dataBean: CurrencyInfoBean){
        val dialog= DiscernTipsDialog(this, R.style.dialog)
        dialog.setCurrencyData(dataBean,currentPic)
        dialog.show()
    }

    override fun onResume() {
        super.onResume()
        // 显示最新的图像
        val images = Utils.getFilesAllName(PathUtils.getExternalAppPicturesPath())
        if (images.isNotEmpty()) {
            Glide.with(this@CP)
                .load(images[images.size - 1])
                .apply(RequestOptions.circleCropTransform())
                .into(photoViewButton!!)
        } else {
            Glide.with(this@CP)
                .load(R.drawable.camera_ic_photo)
                .apply(RequestOptions.circleCropTransform())
                .into(photoViewButton!!)
        }
    }

    // 启动相机
    @SuppressLint("LongLogTag")
    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this@CP)
        cameraProviderFuture.addListener({
            // 绑定生命周期
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()

            // 设置相机支持预览
            val preview = Preview.Builder().build()
            preview.setSurfaceProvider(viewFinder?.surfaceProvider);

            // 设置相机支持拍照
            imageCapture = ImageCapture.Builder()
                // 设置闪光灯
                .setFlashMode(flashMode)
                // 设置照片质量
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build()

            // 设置相机支持图像分析
            val imageAnalysis = ImageAnalysis.Builder()
                .setTargetAspectRatio(AspectRatio.RATIO_4_3)
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build()

            // 实时获取图像进行分析
            imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(this)) { image ->
                if (isInfer) {
                    // 执行人脸检测
                    infer(image)
                }
            }

            try {
                // 在重新绑定之前取消绑定用例
                cameraProvider.unbindAll()

                // 将用例绑定到摄像机
                val camera: Camera = cameraProvider.bindToLifecycle(
                    this,
                    cameraSelector,
                    preview,
                    imageCapture,
                    imageAnalysis
                )
                // 相机控制，如点击
                mCameraControl = camera.cameraControl
                mCameraInfo = camera.cameraInfo
                initCameraListener()
            } catch (exc: Exception) {
                Log.e(TAG, "Use case binding failed", exc)
            }

        }, ContextCompat.getMainExecutor(this))
    }

    // 人脸检测
    @SuppressLint("UnsafeExperimentalUsageError", "WrongViewCast", "UnsafeOptInUsageError")
    private fun infer(image: ImageProxy) {
        if (!::bitmapBuffer.isInitialized) {
            imageRotationDegrees = image.imageInfo.rotationDegrees
            Log.d("测试", "方向：$imageRotationDegrees")
            bitmapBuffer = Bitmap.createBitmap(image.width, image.height, Bitmap.Config.ARGB_8888)
        }

        // 将图像转换为RGB，并将其放在bitmapBuffer
        image.use { converter.yuvToRgb(image.image!!, bitmapBuffer) }

        // 画框
        val boxPre: View = findViewById<View>(R.id.box_prediction)
        (boxPre.layoutParams as ViewGroup.MarginLayoutParams).apply {
            topMargin = 20
            leftMargin = 30
            width = 400
            height = 500
        }
    }

    // 拍照
    private fun takePhoto() {
        // 保证相机可用
        val imageCapture = imageCapture ?: return

        val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
            .toString() + File.separator + "Camera"
        // 保存路径
        val photoFile =
            File(path, "" + System.currentTimeMillis() + ".png")

        // 创建包含文件和metadata的输出选项对象
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

        // 设置图像捕获监听器，在拍照后触发
        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                @SuppressLint("LongLogTag")
                override fun onError(exc: ImageCaptureException) {
                    Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    val fileSize = FileUtil.getFileSize(photoFile.absolutePath)
                    val compressQuality:String = FileUtil.compressQuality(this@CP,photoFile.absolutePath)
                    val fileSize2 = FileUtil.getFileSize(compressQuality)
                    Log.d("HttpManager","压缩前"+fileSize+"压缩后"+fileSize2)
                    toUploadPrc(compressQuality)
                }
            })
    }

    // 相机点击等相关操作监听
    private fun initCameraListener() {
        val cameraXPreviewViewTouchListener = EZ(this)

        cameraXPreviewViewTouchListener.setCustomTouchListener(object :
            EZ.CustomTouchListener {
            // 放大缩小操作
            override fun zoom(delta: Float) {
            }

            // 点击操作
            @SuppressLint("LongLogTag")
            override fun click(x: Float, y: Float) {
                Log.d(TAG, "单击")
                val factory = viewFinder?.meteringPointFactory
                // 设置对焦位置
                val point = factory?.createPoint(x, y)
                val action = FocusMeteringAction.Builder(point!!, FocusMeteringAction.FLAG_AF)
                    // 3秒内自动调用取消对焦
                    .setAutoCancelDuration(3, TimeUnit.SECONDS)
                    .build()
                // 执行对焦
                focusView!!.startFocus(Point(x.toInt(), y.toInt()))
                val future: ListenableFuture<*> = mCameraControl!!.startFocusAndMetering(action)
                future.addListener({
                    try {
                        // 获取对焦结果
                        val result = future.get() as FocusMeteringResult
                        if (result.isFocusSuccessful) {
                            focusView!!.onFocusSuccess()
                        } else {
                            focusView!!.onFocusFailed()
                        }
                    } catch (e: java.lang.Exception) {
                        Log.e(TAG, e.toString())
                    }
                }, ContextCompat.getMainExecutor(this@CP))
            }

            // 双击操作
            override fun doubleClick(x: Float, y: Float) {

            }

            override fun longPress(x: Float, y: Float) {
//                Log.d(Companion.TAG, "长按")
            }
        })
        // 添加监听事件
        viewFinder?.setOnTouchListener(cameraXPreviewViewTouchListener)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 关闭相机
        cameraExecutor.shutdown()
    }

    // 权限申请
    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(baseContext, it) == PackageManager.PERMISSION_GRANTED
    }

    // 权限申请结果
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            hasGetPermission = true
            if (allPermissionsGranted()) {
                startCamera()
            } else {
                Toast.makeText(this, "没有相机授权与本地存储权限授权，无法使用！", Toast.LENGTH_SHORT).show()
                finish()
            }
        }
    }



    private fun setWindowBrightness(brightness: Float) {
        val window = window
        val lp = window.attributes
        lp.screenBrightness = brightness
        window.attributes = lp
    }

    private fun getWindowBrightness(): Float {
        val window = window
        val lp = window.attributes
        return lp.screenBrightness
    }
}